# Declare a shader file (.glsl) to be one part of the target sources
# thus when the shader file is modified, it will be re-compiled and
# updated on every build.
# The executable will have access to those .spv files with path like
# <executable directory>/assets/shaders/<shader file name>.spv
function(add_shader TARGET SHADER)
    # Find glslc shader compiler.
    find_program(GLSLC glslc PATHS $ENV{PATH} REQUIRED)
    set(current-shader-path ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER})
    file(RELATIVE_PATH tpath ${PROJECT_SOURCE_DIR} ${current-shader-path})
    set(current-output-path ${PROJECT_BINARY_DIR}/${tpath})
    set(current-output-path ${current-output-path}.spv)
    # Add a custom command to compile GLSL to SPIR-V.
    get_filename_component(current-output-dir ${current-output-path} DIRECTORY)
    file(MAKE_DIRECTORY ${current-output-dir})
    file(TO_NATIVE_PATH ${current-shader-path} current-shader-path-native)
    file(TO_NATIVE_PATH ${current-output-path} current-output-path-native)
    add_custom_command(
            OUTPUT ${current-output-path}
            COMMAND ${GLSLC} -o ${current-output-path-native} ${current-shader-path-native}
            MAIN_DEPENDENCY ${current-shader-path}
            IMPLICIT_DEPENDS CXX ${current-shader-path} # 只有在Makefile生成器下有用，注意！
            COMMENT Generating bitfile for shader '${SHADER}'
            VERBATIM)
    # Make sure our native build depends on this output.
    set_source_files_properties(${current-output-path} PROPERTIES GENERATED TRUE
            TARGET_DIRECTORY ${TARGET})
    target_sources(${TARGET} PRIVATE ${current-output-path})

endfunction(add_shader)

# Declare a script file (.lua) to be one part of the target sources
# so the executable built anywhere can have access to them with path
# <executable directory>/scripts/<script>
function(add_script TARGET SCRIPT)
    get_filename_component(script-output-path ${PROJECT_BINARY_DIR}/scripts/${SCRIPT} ABSOLUTE)
    get_filename_component(script-source-path ${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT} ABSOLUTE)
    # Copy the script only while building in another directory
    if(NOT ${script-output-path} STREQUAL ${script-source-path})
        get_filename_component(script-output-dir ${script-output-path} DIRECTORY)
        file(MAKE_DIRECTORY ${script-output-dir})
        file(TO_NATIVE_PATH ${script-output-path} script-output-path-native)
        file(TO_NATIVE_PATH ${script-source-path} script-source-path-native)
        add_custom_command(
            OUTPUT ${script-output-path}
            COMMAND ${CMAKE_COMMAND} -E copy ${script-source-path-native} ${script-output-path-native}
            MAIN_DEPENDENCY ${script-source-path}
            COMMENT Copying script file '${SCRIPT}')
        set_source_files_properties(${script-output-path} PROPERTIES GENERATED TRUE
                TARGET_DIRECTORY ${TARGET})
        target_sources(${TARGET} PRIVATE ${script-output-path})
    endif()
endfunction(add_script)


# Declare a compile-time asset.
function(add_asset TARGET RESOURCE)
    get_filename_component(resource-source-path ${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE} ABSOLUTE)
    file(RELATIVE_PATH tpath ${PROJECT_SOURCE_DIR} ${resource-source-path})
    get_filename_component(resource-output-path ${PROJECT_BINARY_DIR}/${tpath} ABSOLUTE)
    # Copy the asset only while building in another directory
    if(NOT ${resource-output-path} STREQUAL ${resource-source-path})
        get_filename_component(resource-output-dir ${resource-output-path} DIRECTORY)
        file(MAKE_DIRECTORY ${resource-output-dir})
        file(TO_NATIVE_PATH ${resource-output-path} resource-output-path-native)
        file(TO_NATIVE_PATH ${resource-source-path} resource-source-path-native)
        add_custom_command(
                OUTPUT ${resource-output-path}
                COMMAND ${CMAKE_COMMAND} -E copy ${resource-source-path-native} ${resource-output-path-native}
                MAIN_DEPENDENCY ${resource-source-path}
                COMMENT Copying resource file '${RESOURCE}')
        set_source_files_properties(${resource-output-path} PROPERTIES GENERATED TRUE
                TARGET_DIRECTORY ${TARGET})
        target_sources(${TARGET} PRIVATE ${resource-output-path})
    endif()
endfunction(add_asset)